package com.cl.cloud.binlog.tableMeta;

import com.cl.cloud.binlog.content.BinLogApplicationContext;
import com.cl.cloud.binlog.properties.DbConfig;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.sql.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: 数据库表映射工厂类
 * @author: liuzijian
 * @time: 2021-12-21 14:28
 */
@Slf4j
public class TableMetaFactory {

    @Getter
    private final DbConfig dbConfig;
    @Getter
    private final BinLogApplicationContext context;

    public TableMetaFactory(DbConfig dbConfig, BinLogApplicationContext context) {
        this.dbConfig = dbConfig;
        this.context = context;
    }

    //缓存tableId信息
    private final Map<String, TableMetaEntity> tableMetaEntityIdMap = new HashMap<>();

    private String getKey(Long tableId) {
        return dbConfig.getHost() + ":" + dbConfig.getPort() + "#" + tableId;
    }

    /**
     * 获取表映射实体
     * @param tableId
     * @param dbName
     * @param tableName
     * @return
     */
    public TableMetaEntity getTableMetaEntity(Long tableId, String dbName, String tableName) {
        if(!context.getTableFilter().filter(tableName)){//过滤掉不存在filter里面的表
            return null;
        }
        Connection connection = null;
        try {
            String key = this.getKey(tableId);
            if (tableMetaEntityIdMap.get(key) != null) {
                return tableMetaEntityIdMap.get(key);
            } else {
                String url = "jdbc:mysql://" + dbConfig.getHost() + ":" + dbConfig.getPort() + "/" + dbName;
                connection = DriverManager.getConnection(url, dbConfig.getUserName(), dbConfig.getPassword());
                DatabaseMetaData dbmd = connection.getMetaData();
                ResultSet rs = dbmd.getColumns(dbName, dbName, tableName, null);
                TableMetaEntity tableMetaEntity = new TableMetaEntity();
                tableMetaEntity.setTableId(tableId);
                tableMetaEntity.setDbName(dbName);
                tableMetaEntity.setTableName(tableName);
                tableMetaEntity.setEntityClass(context.getTableFilter().getTableNameMap().get(tableName));
                while (rs.next()) {
                    ColumnMetaData columnMetaData = new ColumnMetaData();
                    String colName = rs.getString("COLUMN_NAME");
                    columnMetaData.setName(colName);
                    String dbType = rs.getString("TYPE_NAME");
                    columnMetaData.setType(dbType);
                    tableMetaEntity.getColumnMetaDataList().add(columnMetaData);
                }
                tableMetaEntityIdMap.put(key, tableMetaEntity);
                return tableMetaEntity;
            }
        } catch (Exception e) {
            log.error("数据库表映射工厂类错误", e);
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                }
            }
        }
        return null;
    }

    /**
     * 获取表映射实体
     * @param tableId
     * @return
     */
    public TableMetaEntity getTableMetaEntity(Long tableId) {
        //log.info("数据库表缓存：{}", JsonUtil.toJson(tableMetaEntityIdMap));
        String key = this.getKey(tableId);
        return tableMetaEntityIdMap.get(key);
    }

}
